#ifndef AXISRENDERER_H
#define AXISRENDERER_H

#include <vector>

#include <qrender/renderer.h>

class SphereRenderer;
class ConeRenderer;
class LineRenderer;

class AxisRenderer : public Renderer
{
public:
    AxisRenderer();
    ~AxisRenderer();

    void setPose(const std::vector<double> &pose);

    /**
     * @brief setColor 设置坐标轴颜色
     * @param x_color x 轴颜色
     * @param y_color y 轴颜色
     * @param z_color z 轴颜色
     */
    void setColor(QVector4D x_color, QVector4D y_color, QVector4D z_color);
    inline void setColor(QVector4D color) { setColor(color, color, color); }

    /**
     * @brief setShape 设置形状
     * @param cone_height 箭头圆锥高度 = 直线长度 / 2
     * @param cone_radius 箭头圆锥半径 = 原点半径 / 2
     */
    void setShape(float cone_height, float cone_radius);

    /**
     * @brief setFixedSize 固定坐标系大小
     * @param fixed_size 是否固定
     */
    void setFixedSize(bool fixed_size, float fixed_length = 0.0);

protected:
    void create() override;
    void render(const CameraInfo &camera) override;
    void release() override;

private:
    /// 生成坐标轴顶点坐标
    void generateAxisVertices();

    void scale(CameraInfo &camera, float factor);

private:
    // 基本属性
    /// x, y, z, rx, ry, rz
    std::vector<double> pose_{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
    QVector4D x_color_{ 1.0, 0.0, 0.0, 1.0 };
    QVector4D y_color_{ 0.0, 1.0, 0.0, 1.0 };
    QVector4D z_color_{ 0.0, 0.0, 1.0, 1.0 };
    float cone_height_{ 20.0f }; ///< 箭头圆锥高度 = 直线长度 / 2
    float cone_radius_{ 5.0f };  ///< 箭头圆锥半径 = 原点半径 / 2

    // 固定尺寸功能
    bool fixed_size_{ false };    ///< 是否固定尺寸
    float fixed_distance_{ 0.0 }; ///< 固定的距原点距离

    float fixed_cone_height_{ 20.0f }; ///< 固定的尺寸
    float fixed_cone_radius_{ 5.0f };  ///< 固定的尺寸

    float last_camera_distance_{ 0.0 }; ///< 上次相机到原点距离

    // 渲染数据
    std::shared_ptr<SphereRenderer> r_origin_{ nullptr };

    std::shared_ptr<ConeRenderer> r_cone_x_{ nullptr };
    std::shared_ptr<ConeRenderer> r_cone_y_{ nullptr };
    std::shared_ptr<ConeRenderer> r_cone_z_{ nullptr };

    std::shared_ptr<LineRenderer> r_line_x_{ nullptr };
    std::shared_ptr<LineRenderer> r_line_y_{ nullptr };
    std::shared_ptr<LineRenderer> r_line_z_{ nullptr };
};

#endif // AXISRENDERER_H
